<script setup lang="ts">
import { ref, computed } from "vue";
import { message } from "@/utils/message";
import Add from "@iconify-icons/ep/plus";
import Eye from "@iconify-icons/ri/eye-line";
import Delete from "@iconify-icons/ri/delete-bin-7-line";
import Sortable from "sortablejs";
import type { UploadFile } from "element-plus";
import { getKeyList } from "@pureadmin/utils";

const curOpenImgIndex = ref(0);
const dialogVisible = ref(false);
const urlList = computed(() => getKeyList(fileList.value, "url"));

const props = defineProps({
  limit: {
    type: Number,
    default: 3
  },
  imageList: {
    type: Array,
    default: () => []
  }
});
console.log(props.imageList);
const fileList = ref(props.imageList ?? []);
/** 超出最大上传数时触发 */
const onExceed = () => {
  message(`最多上传${props.limit}张图片，请先删除在上传`);
};
/** 上传文件前校验 */
const onBefore = file => {
  if (!["image/jpeg", "image/png", "image/gif"].includes(file.type)) {
    message("只能上传图片");
    return false;
  }
  const isExceed = file.size / 1024 / 1024 > 2;
  if (isExceed) {
    message(`单个图片大小不能超过2MB`);
    return false;
  }
};
const getUploadItem = () => document.querySelectorAll("#pure-upload-item");
/** 缩略图拖拽排序 */
const imgDrop = uid => {
  const CLASSNAME = "el-upload-list";
  const _curIndex = fileList.value.findIndex(img => img.uid === uid);
  getUploadItem()?.[_curIndex]?.classList?.add(`${CLASSNAME}__item-actions`);
  const wrapper: HTMLElement = document.querySelector(`.${CLASSNAME}`);
  Sortable.create(wrapper, {
    handle: `.${CLASSNAME}__item`,
    onEnd: ({ newIndex, oldIndex }) => {
      const oldFile = fileList.value[oldIndex];
      fileList.value.splice(oldIndex, 1);
      fileList.value.splice(newIndex, 0, oldFile);
      // fix: https://github.com/SortableJS/Sortable/issues/232 (firefox is ok, but chromium is bad. see https://bugs.chromium.org/p/chromium/issues/detail?id=410328)
      getUploadItem().forEach(ele => {
        ele.classList.remove(`${CLASSNAME}__item-actions`);
      });
    }
  });
};
/** 大图预览 */
const handlePictureCardPreview = (file: UploadFile) => {
  curOpenImgIndex.value = fileList.value.findIndex(img => img.uid === file.uid);
  dialogVisible.value = true;
};

/** 移除上传的文件 */
const handleRemove = (file: UploadFile) => {
  fileList.value.splice(fileList.value.indexOf(file), 1);
};
</script>

<template>
  <el-upload
    v-model:file-list="fileList"
    drag
    multiple
    class="pure-upload"
    list-type="picture-card"
    accept="image/jpeg,image/png,image/gif"
    action="https://run.mocky.io/v3/3aa761d7-b0b3-4a03-96b3-6168d4f7467b"
    :limit="props.limit"
    :headers="{ Authorization: 'eyJhbGciOiJIUzUxMiJ9.admin' }"
    :on-exceed="onExceed"
    :before-upload="onBefore"
  >
    <IconifyIconOffline :icon="Add" class="m-auto mt-4" width="30" />
    <template #file="{ file }">
      <div
        v-if="file.status == 'ready' || file.status == 'uploading'"
        class="mt-[35%] m-auto"
      >
        <p class="font-medium">文件上传中</p>
        <el-progress
          class="mt-2"
          :stroke-width="2"
          :text-inside="true"
          :show-text="false"
          :percentage="file.percentage"
        />
      </div>
      <div v-else @mouseenter.stop="imgDrop(file.uid)">
        <img
          class="select-none el-upload-list__item-thumbnail"
          :src="file.url"
        />
        <span
          id="pure-upload-item"
          :class="[
            'el-upload-list__item-actions',
            fileList.length > 1 && '!cursor-move'
          ]"
        >
          <span
            title="查看"
            class="hover:text-primary"
            @click="handlePictureCardPreview(file)"
          >
            <IconifyIconOffline
              :icon="Eye"
              class="duration-100 hover:scale-125"
            />
          </span>
          <span class="el-upload-list__item-delete" @click="handleRemove(file)">
            <span title="移除" class="hover:text-[var(--el-color-danger)]">
              <IconifyIconOffline
                :icon="Delete"
                class="duration-100 hover:scale-125"
              />
            </span>
          </span>
        </span>
      </div>
    </template>
  </el-upload>
  <!-- 有时文档没写并不代表没有，多看源码好处多多😝 https://github.com/element-plus/element-plus/tree/dev/packages/components/image-viewer/src （emm...这让我想起刚开始写这个项目时，很多东西只有英文或者没有文档，需要看源码时，想笑🥹。那些美好时光都给这些坑了，giao） -->
  <el-image-viewer
    v-if="dialogVisible"
    :initialIndex="curOpenImgIndex"
    :url-list="urlList"
    :zoom-rate="1.2"
    :max-scale="7"
    :min-scale="0.2"
    @close="dialogVisible = false"
    @switch="index => (curOpenImgIndex = index)"
  />
</template>

<style lang="scss" scoped>
:deep(.el-upload--picture-card) {
  width: 100px;
  height: 100px;
  .el-upload-dragger {
    background-color: transparent;
    border: none;
    height: 100px;
    padding: 0;
    display: flex;
    .mt-4 {
      margin-top: auto;
    }
  }
}
:deep(.el-upload-list__item) {
  width: 100px;
  height: 100px;
}

.img-name {
  position: absolute;
  bottom: 80px;
  left: 50%;
  z-index: 4000;
  padding: 5px 23px;
  background-color: var(--el-text-color-regular);
  border-radius: 22px;
  transform: translateX(-50%);
}
</style>
